﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Newtonsoft.Json;

namespace AreaSpider
{
    class FileSet
    {
        //Area Class Library 项目路径
        static string areaDir = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).Parent.Parent.Parent.FullName + "\\Area";
        //Area Web 项目路径
        static string areaWebDir = Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).Parent.Parent.Parent.FullName + "\\AreaWeb";
        //xml备份路径
        static string backupXmlDir = areaDir + "\\backup" + "\\xml";
        //Json备份路径
        static string backupJsonDir = areaWebDir + "\\backup" + "\\json";
        //xml文件保存路径
        static string saveXmlPath = areaDir + "\\area.xml";
        //Json文件保存路径(带区级)
        static string saveJsonPath = areaWebDir + "\\js\\area.json";
        //Json文件保存路径(不带区级)
        static string saveJsonPath_NoCounty = areaWebDir + "\\js\\area_nocounty.json";

        public static int SaveFile(List<Area> areaLst, string url)
        {
            if (areaLst == null || areaLst.Count == 0) return 0;
            try
            {
                SaveXml(areaLst, url);
                return 1;        
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("保存文件失败：" + ex.Message);
                return 0;
            }


            //Console.WriteLine(areaLst.Count);
        }

        public static void SaveXml(List<Area> areaLst, string url)
        {
            XmlDocument doc = new XmlDocument();
            //声明节点
            XmlNode node = doc.CreateXmlDeclaration("1.0", "utf-8", "");
            doc.AppendChild(node);
            //根节点  
            XmlNode rootN = doc.CreateElement("area");
            rootN.Attributes.Append(CreateAttribute(rootN, "create_time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
            rootN.Attributes.Append(CreateAttribute(rootN, "url", url));
            doc.AppendChild(rootN);
            //先处理省信息
            List<Area> proLst = areaLst.Where(ar => int.Parse(ar.Code) % 10000 == 0).ToList();
            foreach (Area pro in proLst)
            {
                //添加省节点
                XmlNode proN = doc.CreateElement("province");
                //setAttribute(proN, pro);
                SetChildNode(proN, pro);
                rootN.AppendChild(proN);
                //找到省份下的城市,如果是直辖市等于省本身
                List<Area> cityLst = areaLst.Where(ar =>
                    (int.Parse(ar.Code) % 10000 != 0 && int.Parse(ar.Code) % 100 == 0
                    && int.Parse(ar.Code) / 10000 == int.Parse(pro.Code) / 10000)
                    || ((pro.Code == "110000" || pro.Code == "120000" || pro.Code == "310000" || pro.Code == "500000")
                      && ar.Code == pro.Code)).ToList();
                foreach (Area city in cityLst)
                {
                    //添加市节点
                    XmlNode cityN = doc.CreateElement("city");
                    //setAttribute(cityN, city);
                    SetChildNode(cityN, city);
                    proN.AppendChild(cityN);
                    //找到城市下的区/县，如果是直辖市，代码前两位相等即可
                    List<Area> countyLst = areaLst.Where(ar =>
                    (int.Parse(ar.Code) % 100 != 0 && int.Parse(ar.Code) / 100 == int.Parse(city.Code) / 100)
                    || ((city.Code == "110000" || city.Code == "120000" || city.Code == "310000" || city.Code == "500000")
                      && ar.Code != city.Code && ar.Code.Substring(0, 2) == city.Code.Substring(0, 2))).ToList();

                    foreach (Area county in countyLst)
                    {
                        //添加区/县节点
                        XmlNode countyN = doc.CreateElement("county");
                        //setAttribute(countyN, county);
                        SetChildNode(countyN, county);
                        cityN.AppendChild(countyN);
                    }

                }

            }

            //在保存xml文件之前先备份一份   
            if (!Directory.Exists(backupXmlDir)) Directory.CreateDirectory(backupXmlDir);
            if (File.Exists(saveXmlPath))
            {
                File.Copy(saveXmlPath, backupXmlDir + "\\Area_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".xml");
            }
            //保存xml文件
            doc.Save(saveXmlPath);
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("xml文件已生成：" + saveXmlPath);


            SaveJson(doc);
        }

        public static void SaveJson(XmlDocument doc)
        {
            if (!Directory.Exists(backupJsonDir)) Directory.CreateDirectory(backupJsonDir);
            //生成Json格式文本
            string json = JsonConvert.SerializeXmlNode(doc.SelectSingleNode("./area"));
            //保存Json格式文件(带区级) 
            if (File.Exists(saveJsonPath))
            {
                File.Copy(saveJsonPath, backupJsonDir + "\\Area_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".json");
            }            
            
            StreamWriter sw = File.CreateText(saveJsonPath);
            sw.WriteLine(json);
            sw.Flush();
            sw.Close();
            sw.Dispose();

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("json文件(带区级)已生成：" + saveJsonPath);

            //保存Json格式文件(不带区级) 
            if (File.Exists(saveJsonPath_NoCounty))
            {
                File.Copy(saveJsonPath_NoCounty, backupJsonDir + "\\Area_NoCounty_" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".json");
            }
            var countNodeList = doc.GetElementsByTagName("county");
            if (countNodeList != null)
            {
                for (int i = countNodeList.Count; i >= 0; i--)
                {
                    if (countNodeList[i] != null)
                        countNodeList[i].ParentNode.RemoveChild(countNodeList[i]);
                }
            }
            string json_nocounty = JsonConvert.SerializeXmlNode(doc.SelectSingleNode("./area"));
            sw = File.CreateText(saveJsonPath_NoCounty);
            sw.WriteLine(json_nocounty);
            sw.Flush();
            sw.Close();
            sw.Dispose();

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("json文件(不带区级)已生成：" + saveJsonPath_NoCounty);
        }

        //设置子节点
        public static void SetChildNode(XmlNode node, Area area)
        {
            XmlDocument doc = node.OwnerDocument;

            //XmlNode codeN = doc.CreateElement("code");
            //codeN.InnerText = area.Code;
            //node.AppendChild(codeN);

            XmlNode nameN = doc.CreateElement("name");
            nameN.InnerText = area.Name;
            node.AppendChild(nameN);

            //XmlNode fullpyN = doc.CreateElement("fullpy");
            //fullpyN.InnerText = PinYin.ConvertFull(area.Name);
            //node.AppendChild(fullpyN);

            //XmlNode abbpy = doc.CreateElement("abbpy");
            //abbpy.InnerText = PinYin.ConvertAbb(area.Name);
            //node.AppendChild(abbpy);
        }

        //设置节点属性
        public static void SetAttribute(XmlNode node, Area area)
        {
            //node.Attributes.Append(CreateAttribute(node, "code", area.Code));
            node.Attributes.Append(CreateAttribute(node, "name", area.Name));
            //node.Attributes.Append(CreateAttribute(node, "fullpy", PinYin.ConvertFull(area.Name)));
            //node.Attributes.Append(CreateAttribute(node, "abbpy", PinYin.ConvertAbb(area.Name)));
        }

        public static XmlAttribute CreateAttribute(XmlNode node, string attributeName, string value)
        {
            XmlDocument doc = node.OwnerDocument;
            XmlAttribute attr = null;
            attr = doc.CreateAttribute(attributeName);
            attr.Value = value;
            node.Attributes.SetNamedItem(attr);
            return attr;
        }

        public static void buildAreaDll()
        {

        }

    }
}
